﻿using System.Collections.ObjectModel;
using Brjnk.MVVM;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Tests
{
    [TestClass()]
    public class CollectionWrapperTest
    {
        private TestContext testContextInstance;

        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        [TestMethod()]
        public void CollectionWrapperConstructorTest()
        {
            var observable = new ObservableCollection<string>();
            observable.Add("A");
            observable.Add("B");

            var c = new CollectionWrapper<string, Wrapper>(observable);
            c.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(c_CollectionChanged);
            Assert.AreEqual("A", c[0].GetWrappedObject());
            Assert.AreEqual("B", c[1].GetWrappedObject());
            Assert.AreEqual(2, c.Count);
            observable.Add("C");
            Assert.AreEqual(3, c.Count);
            Assert.AreEqual("C", c[2].GetWrappedObject());
            observable.Move(0, 2);

            Assert.AreEqual("B", c[0].GetWrappedObject());
            Assert.AreEqual("C", c[1].GetWrappedObject());
            Assert.AreEqual("A", c[2].GetWrappedObject());
            observable.RemoveAt(1);

            Assert.AreEqual(2, c.Count);
            Assert.AreEqual("B", c[0].GetWrappedObject());
            Assert.AreEqual("A", c[1].GetWrappedObject());
            observable[0] = "C";
            Assert.AreEqual("C", c[0].GetWrappedObject());
            Assert.AreEqual("A", c[1].GetWrappedObject());
            observable.Clear();
            Assert.AreEqual(0, c.Count);
            Assert.AreEqual(5, catchedEvents);

            c.Add(new Wrapper("A", "A".GetHashCode()));
            c.Add(new Wrapper("B", "B".GetHashCode()));
            c[0] = new Wrapper("C", "C".GetHashCode());

            Assert.AreEqual(c[0].Value, "C".GetHashCode());
            Assert.AreEqual(c[1].Value, "B".GetHashCode());
            Assert.AreEqual(c[0].GetWrappedObject(), "C");
            Assert.AreEqual(c[1].GetWrappedObject(), "B");
            Assert.AreEqual(observable[0], "C");
            Assert.AreEqual(observable[1], "B");
        }

        private int catchedEvents = 0;

        private void c_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            catchedEvents++;
        }
    }

    internal class Wrapper : IWrapper<string>
    {
        private string str;

        public Wrapper(string str)
        {
            this.str = str;
        }

        public Wrapper(string str, int value)
        {
            this.str = str;
            Value = value;
        }

        public int Value { get; set; }

        public string GetWrappedObject()
        {
            return str;
        }

        public void Release()
        {
        }

        public object GetWrappedObjectUntyped()
        {
            return GetWrappedObject();
        }
    }
}